package decomposition;

import matrix_operations.Matrix;

public abstract class Cholesky {
	
	private static String msg ="";

	public static Matrix factorizing(Matrix A) {
		
		msg = "";

		if (A.getN() != A.getM()) {
			msg = "Erro! The matrix can not be facored, because is not a square matrix."; 
			System.out.println(msg);
			return null;
		}

		int n = A.getN();
		Matrix L = Matrix.getIdentityMatrix(n);


		double sum = 0;

		for (int i = 0; i < n; i++) {

			sum = 0;
			for (int j = 0; j < i; j++){
				sum += Math.pow(L.getValue(i, j), 2);
			}
				
			
			if ((A.getValue(i, i) - sum) <= 0){
				msg = "Erro! The matrix can not be facored, because is not a positve definite."; 
				System.out.println(msg);
				return null;				
			}
				
			L.setValue(i, i, Math.sqrt(A.getValue(i, i) - sum));
			

			for (int j = i + 1; j < n; j++) {

				sum = 0;
				for (int k = 0; k < i; k++)
					sum += L.getValue(j, k) * L.getValue(i, k);

				if (L.getValue(i, i) == 0) {
					msg = "Erro! The Matrix cannot be factored with Cholesky's method"; 
					System.out.println(msg);
					return null;
				}
				
				L.setValue(j, i, (A.getValue(j, i) - sum) / L.getValue(i, i));
			}

		}

		return L;
	}

	public static Matrix solveSysem(Matrix L, Matrix B) {
		
		if (L == null){
			msg = "Erro! The Matrix cannot be factored with Cholesky's method"; 
			return null;
		}		

		
		Matrix y = new Matrix(B.getN(), 1);
		Matrix x = new Matrix(B.getN(), 1);
		double sum = 0;
		
		msg = "";

		// Ly = B
		for (int i = 0; i < B.getN(); i++) {
			sum = 0;
			for (int j = 0; j < i; j++) {
				sum += L.getValue(i, j) * y.getValue(j, 0);
			}
			y.setValue(i, 0, (B.getValue(i, 0) - sum) / L.getValue(i, i));
		}

		// Ltx = y
		for (int i = B.getN() - 1; i >= 0; i--) {
			sum = 0;
			for (int j = i; j < B.getN(); j++)
				sum += L.getValue(j, i) * x.getValue(j, 0);
			x.setValue(i, 0, (y.getValue(i, 0) - sum) / L.getValue(i, i));
		}

		return x;
	}
	
	public static String getMsg(){
		return msg;
	}
}
